/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package settings;

import java.util.logging.Level;
import java.util.logging.Logger;
import settings.collections.elements.SettingsManager;
import settings.collections.CarCollection;
import settings.collections.ETypeCollection;
import settings.collections.SchleifenCollection;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import settings.collections.AusrueckordnungCollection;
import settings.collections.ControllCenterSettings;
import settings.collections.elements.ColorSettings;

/**
 *
 * @author rbs
 */
public final class MainSettingsManager {

    private static MainSettingsManager mainSettingsManagerInstance;
    //Collections:
    private static CarCollection carCollection = new CarCollection();
    private static ETypeCollection eTypeCollection = new ETypeCollection();
    private static SchleifenCollection schleifenCollection = new SchleifenCollection();
    private static AusrueckordnungCollection ausrueckordnungCollection = new AusrueckordnungCollection();
    private static ColorSettings colorSettings = new ColorSettings();
    private static ControllCenterSettings centerSettings = new ControllCenterSettings();
    
    private static ArrayList<String> readFailed = new ArrayList<String>();

    
    private MainSettingsManager() {
    }
   
    
    public static void save(){
        try {
            writeObjToFile(carCollection);
            writeObjToFile(schleifenCollection);
            writeObjToFile(eTypeCollection);
            writeObjToFile(ausrueckordnungCollection);
            writeObjToFile(centerSettings);
        } catch (IOException ex) {
            Logger.getLogger(MainSettingsManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public static void reset() {
        carCollection = new CarCollection();
        eTypeCollection = new ETypeCollection();
        schleifenCollection = new SchleifenCollection();
        ausrueckordnungCollection = new AusrueckordnungCollection();
        colorSettings = new ColorSettings();
        centerSettings = new ControllCenterSettings();
        
        //reset fails:
        readFailed = new ArrayList<String>();
    }

    public static void load() {
        File file = new File(carCollection.getFileName());
        if (file.exists()) {
            try {
                carCollection = (CarCollection) readObjFromFile(carCollection.getFileName());
                if(carCollection != null)
                    System.out.println("Loaded " + carCollection.getCars().size() + " cars from SettingsFile");
            } catch (Exception ex) {
                Logger.getLogger(MainSettingsManager.class.getName()).log(Level.SEVERE, null, ex);
                
                System.out.println("");
            }
        } else {
            carCollection = new CarCollection();
            System.out.println("New carCollection created.");
        }


        file = new File(schleifenCollection.getFileName());
        if (file.exists()) {
            schleifenCollection = (SchleifenCollection) readObjFromFile(schleifenCollection.getFileName());
            if (schleifenCollection != null)
                System.out.println("Loaded " + schleifenCollection.getSchleifen().size() + " Schleifen from SettingsFile");
        } else {
            schleifenCollection = new SchleifenCollection();
            System.out.println("New SchleifenCollection created.");
        }

        file = new File(eTypeCollection.getFileName());
        if (file.exists()) {
            eTypeCollection = (ETypeCollection) readObjFromFile(eTypeCollection.getFileName());
            if (eTypeCollection != null)
                System.out.println("Loaded " + eTypeCollection.getETypes().size() + " eTypes from SettingsFile");
        } else {
            eTypeCollection = new ETypeCollection();
            System.out.println("New eTypeCollection created.");
        }
        
        file = new File(ausrueckordnungCollection.getFileName());
        if (file.exists()) {
            ausrueckordnungCollection = (AusrueckordnungCollection) readObjFromFile(ausrueckordnungCollection.getFileName());
            if(ausrueckordnungCollection != null)
                System.out.println("Loaded " + ausrueckordnungCollection.getAROs().size() + " AROs from SettingsFile");
        } else {
            ausrueckordnungCollection = new AusrueckordnungCollection();
            System.out.println("New AROCollection created.");
        }
        
        file = new File(centerSettings.getFileName());
        if (file.exists()) {
            centerSettings = (ControllCenterSettings) readObjFromFile(centerSettings.getFileName());
            System.out.println("Loaded ControlCenter from SettingsFile");
        } else {
            centerSettings = new ControllCenterSettings();
            System.out.println("New ControlCenterSetting created.");
        }
        
        
        if (readFailed.size() > 0)
        {
            String msg = "Eine oder mehrere Einstellungsdateien konnten nicht geladen werden, weil sie mit dieser Version nicht kompatibel sind:\n\r.";
            for (String fileName: readFailed)
                msg += fileName + "\r\n";
            
            msg += "Die Dateien werden im Ordner settings" + File.separator + "backup gesichert. Die alten Einstellungen gehen leider verloren.";
            
            JOptionPane.showMessageDialog(null, msg, "Fehler beim Laden der Einstellungen", JOptionPane.WARNING_MESSAGE);
            
            
            for (String fileName: readFailed)
            {
                File backup = new File("settings" + File.separator + "backup" + File.separator);
                if (!backup.exists())
                    backup.mkdirs();
                System.out.println("Backuping File: " + fileName);
                File oldFile = new File(fileName);
                File newFile = new File(backup.getAbsolutePath() + File.separator + oldFile.getName());
                if (newFile.exists())
                    newFile.delete();
                boolean success = oldFile.renameTo(newFile);
                System.out.println("renaming from " + oldFile.getAbsolutePath() + " to " + newFile.getAbsolutePath() + ": " + success);
            }
            reset();
            load();
        }
        
    }

    public CarCollection getCarCollection() {
        return carCollection;
    }

    public void setCarSettings(CarCollection carSettings) {
        MainSettingsManager.carCollection = carSettings;
    }

    public ETypeCollection geteTypeCollection() {
        return eTypeCollection;
    }

    public void seteTypeCollection(ETypeCollection eTypeCollection) {
        MainSettingsManager.eTypeCollection = eTypeCollection;
    }

    public SchleifenCollection getSchleifenCollection() {
        return schleifenCollection;
    }

    public void setSchleifenCollection(SchleifenCollection schleifenCollection) {
        MainSettingsManager.schleifenCollection = schleifenCollection;
    }
 
    public AusrueckordnungCollection getAusrueckordnungCollection() {
        return ausrueckordnungCollection;
    }
    
    public static ControllCenterSettings getControlCenterSettings() {
        return centerSettings;
    }
    

    public static synchronized MainSettingsManager getSetting() {
        if (mainSettingsManagerInstance == null) {
            mainSettingsManagerInstance = new MainSettingsManager();
        }
        return mainSettingsManagerInstance;
    }

    public void setSetting(MainSettingsManager instance) {
        MainSettingsManager.mainSettingsManagerInstance = instance;
    }

    public ColorSettings getColorSettings() {
        return colorSettings;
    }
    
    
    private static void writeObjToFile(Object obj) throws IOException {
        SettingsManager setMan = (SettingsManager) obj;
        System.out.println("Writing " + setMan.getName() + " to "
                + setMan.getFileName());
        File file = new File(setMan.getFileName());
        if (!file.exists()) {
            file.getParentFile().mkdir();
            file.createNewFile();
        }
        writeObjToFile(obj, setMan.getFileName());
    }
    

    private static void writeObjToFile(Object object, String fileName) {
        try {
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(fileName)));
            //serialise
            objectOutputStream.writeObject(object);
            objectOutputStream.close();
        } catch (IOException e) {
            System.err.println(e);
        }

    }

    private static Object readObjFromFile(String fileName) {

        ObjectInputStream objectInputStream = null;
        Object obj = null;
        try {
            objectInputStream = new ObjectInputStream(new BufferedInputStream(new FileInputStream(fileName)));
            //deserialise
            obj = objectInputStream.readObject();
            objectInputStream.close();
        } catch (IOException ex) {
            System.out.println("Read failed: " + fileName);
            readFailed.add(fileName);
        } catch (ClassNotFoundException e) {
            System.out.println("Read failed: " + fileName);
            readFailed.add(fileName);
        } finally {
            try {
                objectInputStream.close();
            } catch (Exception e) {
                System.out.println("Fehler beim schließen des fis");
            }
        }

        return obj;
    }
}
